package com.zdxlz.mongodbDemo.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.beans.PropertyEditorSupport;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 类描述：时间操作定义类
 *
 * @Author: 张代浩
 * @Date:2012-12-8 12:15:03
 * @Version 1.0
 */
@Slf4j
public class DateUtils extends PropertyEditorSupport {

    public static ThreadLocal<SimpleDateFormat> date_ym = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM"));
    public static ThreadLocal<SimpleDateFormat> date_sdf = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
    public static ThreadLocal<SimpleDateFormat> yyyyMMdd = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMdd"));
    public static ThreadLocal<SimpleDateFormat> datetimeFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

    // 指定模式的时间格式
    private static SimpleDateFormat getSDFormat(String pattern) {
        return new SimpleDateFormat(pattern);
    }

    /**
     * 当前日历，这里用中国时间表示
     *
     * @return 以当地时区表示的系统当前日历
     */
    public static Calendar getCalendar() {
        return Calendar.getInstance();
    }

    // ////////////////////////////////////////////////////////////////////////////
    // getDate
    // 各种方式获取的Date
    // ////////////////////////////////////////////////////////////////////////////

    /**
     * 当前日期
     *
     * @return 系统当前时间
     */
    public static Date getDate() {
        return new Date();
    }

    /**
     * 指定毫秒数表示的日期
     *
     * @param millis 毫秒数
     * @return 指定毫秒数表示的日期
     */
    public static Date getDate(long millis) {
        return new Date(millis);
    }


    /**
     * 字符串转换时间戳
     *
     * @param str
     * @return
     */
    public static Timestamp str2Timestamp(String str) {
        Date date = str2Date(str, date_sdf.get());
        return new Timestamp(date.getTime());
    }

    /**
     * 字符串转换成日期
     *
     * @param str
     * @param sdf
     * @return
     */
    public static Date str2Date(String str, SimpleDateFormat sdf) {
        if (null == str || "".equals(str)) {
            return null;
        }
        Date date;
        try {
            date = sdf.parse(str);
            return date;
        } catch (ParseException e) {
            log.error("字符串转换成日期解析失败，字符串："+str,e);
        }
        return null;
    }

    /**
     * 日期转换为字符串
     *
     * @param format 日期格式
     * @return 字符串
     */
    public static String getDate(String format) {
        Date date = new Date();
        if (null == date) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    /**
     * 系统当前的时间戳
     *
     * @return 系统当前的时间戳
     */
    public static Timestamp getTimestamp() {
        return new Timestamp(System.currentTimeMillis());
    }

    /**
     * 当前时间，格式 yyyy-MM-dd HH:mm:ss
     *
     * @return 当前时间的标准形式字符串
     */
    public static String now() {
        return datetimeFormat.get().format(getCalendar().getTime());
    }

    // ////////////////////////////////////////////////////////////////////////////
    // formatDate
    // 将日期按照一定的格式转化为字符串
    // ////////////////////////////////////////////////////////////////////////////

    /**
     * 默认方式表示的系统当前日期，具体格式：年-月-日
     *
     * @return 默认日期按“年-月-日“格式显示
     */
    public static String formatDate() {
        return date_sdf.get().format(getCalendar().getTime());
    }

    /**
     * 默认方式表示的系统当前日期，具体格式：yyyy-MM-dd HH:mm:ss
     *
     * @return 默认日期按“yyyy-MM-dd HH:mm:ss“格式显示
     */
    public static String formatDateTime() {
        return datetimeFormat.get().format(getCalendar().getTime());
    }

    /**
     * 默认方式表示的系统当前日期，具体格式：yyyy-MM-dd HH:mm:ss
     *
     * @return 默认日期按“yyyy-MM-dd HH:mm:ss“格式显示
     */
    public static Date getDateTime(String date) {
        try {
            return datetimeFormat.get().parse(date);
        }catch (ParseException e) {
            log.error(e.getMessage());
            return new Date();
        }
    }

    /**
     * 获取时间字符串
     */
    public static String getDataString(SimpleDateFormat formatstr) {
        return formatstr.format(getCalendar().getTime());
    }

    /**
     * 指定日期的默认显示，具体格式：年-月-日
     *
     * @param date 指定的日期
     * @return 指定日期按“年-月-日“格式显示
     */
    public static String formatDate(Date date) {
        return date_sdf.get().format(date);
    }

    /**
     * 默认日期按指定格式显示
     *
     * @param pattern 指定的格式
     * @return 默认日期按指定格式显示
     */
    public static String formatDate(String pattern) {
        return getSDFormat(pattern).format(getCalendar().getTime());
    }

    /**
     * String类型 转换为Date, 如果参数长度为10 转换格式”yyyy-MM-dd“ 如果参数长度为19 转换格式”yyyy-MM-dd
     * HH:mm:ss“ * @param text String类型的时间值
     */
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        if (StringUtils.hasText(text)) {
            try {
                if (!text.contains(":") && text.length() == 10) {
                    setValue(DateUtils.date_sdf.get().parse(text));
                } else if (text.indexOf(":") > 0 && text.length() == 19) {
                    setValue(DateUtils.datetimeFormat.get().parse(text));
                } else {
                    throw new IllegalArgumentException("Could not parse date, date format is error ");
                }
            } catch (ParseException ex) {
                IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage());
                iae.initCause(ex);
                throw iae;
            }
        } else {
            setValue(null);
        }
    }

    public static Date getLastDay() {
        Calendar myTime = Calendar.getInstance();
        myTime.add(Calendar.DATE, -1);
        return myTime.getTime();
    }

    public static String getLastDayFormat() {
        Calendar myTime = Calendar.getInstance();
        myTime.add(Calendar.DATE, -1);
        SimpleDateFormat format1 = date_sdf.get();
        return format1.format(myTime.getTime());
    }

    // 昨天日期
    public static String getLastDay(String thisDay) {
        SimpleDateFormat sdf = date_sdf.get();
        Date today = null;
        try{
            //起始日期
            today = sdf.parse(thisDay);
        }catch(Exception e){
            log.info(e.getMessage());
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(today);
        calendar.add(Calendar.DAY_OF_MONTH,-1);
        Date temp = calendar.getTime();
        return sdf.format(temp);
    }

    // 昨天日期
    public static String getLastDayOfThisMonth(String thisDay) {
        SimpleDateFormat sdf = date_sdf.get();
        Date today = null;
        try{
            //起始日期
            today = sdf.parse(thisDay);
        }catch(Exception e){
            log.info(e.getMessage());
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(today);
        calendar.add(Calendar.MONTH,1);
        calendar.add(Calendar.DAY_OF_MONTH,-1);
        Date temp = calendar.getTime();
        return sdf.format(temp);
    }

    public static Date formatMonthDateToFirstDay(String startDate) {
        SimpleDateFormat format1 = date_sdf.get();
        SimpleDateFormat format2 = date_ym.get();
        Date start = null;
        if (null != startDate) {
            try {
                format1.setLenient(false);
                start = format1.parse(startDate);
            } catch (ParseException ignored1) {
                try {
                    format2.setLenient(false);
                    format2.parse(startDate);
                    startDate = startDate + "-01";
                    start = format1.parse(startDate);
                } catch (ParseException ignored2) {
                    return null;
                }
            }
        }
        return start;
    }

    public static Date formatMonthDateToLastDay(String startDate) {
        SimpleDateFormat format1 = date_sdf.get();
        SimpleDateFormat format2 = date_ym.get();
        Date start = null;
        if (null != startDate) {
            try {
                format1.setLenient(false);
                start = format1.parse(startDate);
            } catch (ParseException ignored1) {
                try {
                    format2.setLenient(false);
                    Date parse = format2.parse(startDate);
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(parse);
                    //获取年
                    int year = calendar.get(Calendar.YEAR);
                    //获取月份，0表示1月份
                    int month = calendar.get(Calendar.MONTH) + 1;
                    //获取本月最大天数
                    int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
                    String lastDate = year+"-"+month+"-"+lastDay;
                    start = format1.parse(lastDate);
                } catch (ParseException ignored2) {
                    return null;
                }
            }
        }
        return start;
    }

    /**
     * time时间是否在newTime之后
     */
    public static boolean isAfterTime(String time, String newTime) {
        if (null == time || null == newTime) {
            return false;
        }
        SimpleDateFormat format1 = datetimeFormat.get();
        SimpleDateFormat format2 = date_sdf.get();
        Date date;
        Date newDate;
        try {
            format1.setLenient(false);
            date = format1.parse(time);
        } catch (ParseException ignored1) {
            try {
                format2.setLenient(false);
                date = format2.parse(time);
            } catch (ParseException ignored2) {
                return false;
            }
        }
        try {
            format1.setLenient(false);
            newDate = format1.parse(newTime);
        } catch (ParseException ignored1) {
            try {
                format2.setLenient(false);
                newDate = format2.parse(newTime);
            } catch (ParseException ignored2) {
                return false;
            }
        }
        if (null == date || null==newDate) {
            return false;
        }
        return date.after(newDate);
    }

    /**
     * 检查是否符合sql时间规范
     * @author SongYang 2022年7月5日
     */
    public static boolean isValidSqlDate(String str) {
        SimpleDateFormat format3 = date_sdf.get();
        try {
            format3.setLenient(false);
            format3.parse(str);
            return true;
        } catch (ParseException ignored) {

        }
        SimpleDateFormat format4 = datetimeFormat.get();
        try {
            format4.setLenient(false);
            format4.parse(str);
            return true;
        } catch (ParseException e) {
            return false;
        }
    }

    /**
     * 获取昨天和endDate中更小的一天
     */
    public static String getEndDate(String endDate) {
        if (null == endDate) {
            return DateUtils.getLastDayFormat();
        }else{
            Date date = DateUtils.formatMonthDateToLastDay(endDate);
            if (null == date) {
                return DateUtils.getLastDayFormat();
            }else {
                Date lastDay = DateUtils.getLastDay();
                if (date.compareTo(lastDay) > 0) {
                    return DateUtils.formatDate(lastDay);
                }else {
                    return endDate;
                }
            }
        }
    }
}
